{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 飞船相遇问题\n",
    "\n",
    "博客：https://blog.csdn.net/weixin_42301220/article/details/127000390\n",
    "\n",
    "3辆飞船A、B、C初始位置分别处于一个边长为$L$的等边三角形的顶点上，即A点坐标为$(\\frac{\\sqrt{3}}{2}L,0)$，B点坐标为$(\\frac{L}{2},0)$，C点坐标为$(-\\frac{L}{2},0)$。飞船飞行过程中，飞船均具有相等的速度$v$，并且A始终朝着B前进，B始终朝着C前进，C始终朝着A前进。\n",
    "\n",
    "\n",
    "\n",
    "<center><img src=\"https://img-blog.csdnimg.cn/08ce89a4000a47c59630bc4e77b08c09.png\" width=50%></center>\n",
    "\n",
    "\n",
    "\n",
    "- 问题1：从初始到$t_1$时刻，飞船A,B,C的运行轨迹（假设采样时间为$\\Delta t$）。\n",
    "- 问题2：到无穷远时刻时，飞船A,B,C最终的状态是怎样的？如果三者速度不相等，那么此时飞船A,B,C最终的状态又是怎样的？请推到分析。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from celluloid import Camera # 保存动图时用，pip install celluloid\n",
    "from matplotlib.animation import FuncAnimation\n",
    "%matplotlib qt5\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 参数设置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 采样时间\n",
    "dt=0.01\n",
    "# 原等边三角形长度\n",
    "L=1\n",
    "# 初始坐标点\n",
    "p_a = np.array([0,np.sqrt(3)/2*L])\n",
    "p_b = np.array([1/2*L,0])\n",
    "p_c = np.array([-1/2*L,0])\n",
    "# 速度\n",
    "v_a = 1.0\n",
    "v_b = 0.8\n",
    "v_c = 0.6\n",
    "\n",
    "\n",
    "\n",
    "p_center=np.array([0,1/np.sqrt(3)/2]) # 等边三角形中心\n",
    "\n",
    "# 存储轨迹\n",
    "trajectory_a=[]\n",
    "trajectory_b=[]\n",
    "trajectory_c=[]\n",
    "\n",
    "# 假设到t时刻停止\n",
    "t = 1\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 迭代公式"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def trajectory_point(p_1,p_2,v):\n",
    "    n_ = (p_2-p_1)/np.linalg.norm(p_2-p_1)\n",
    "    p_now = p_1+n_*v*dt\n",
    "    return p_now"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 求解轨迹"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def all_trajectory(p_1,p_2,p_3,v_a,v_b,v_c):\n",
    "    delta=0\n",
    "    while(delta<t/dt):\n",
    "        p__1=trajectory_point(p_1,p_2,v_a)\n",
    "        p__2=trajectory_point(p_2,p_3,v_b)\n",
    "        p__3=trajectory_point(p_3,p_1,v_c)\n",
    "        delta+=1\n",
    "        p_1,p_2,p_3=p__1,p__2,p__3\n",
    "        trajectory_a.append(p_1)\n",
    "        trajectory_b.append(p_2)\n",
    "        trajectory_c.append(p_3)\n",
    "    return p__1,p__2,p__3\n",
    "\n",
    "\n",
    "all_trajectory(p_a,p_b,p_c,v_a,v_b,v_c)\n",
    "\n",
    "trajectory_a=np.array(trajectory_a)\n",
    "trajectory_b=np.array(trajectory_b)\n",
    "trajectory_c=np.array(trajectory_c)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 画图展示"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "MovieWriter ffmpeg unavailable; using Pillow instead.\n"
     ]
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "camera = Camera(fig)  # 保存动图用\n",
    "for i in range(len(trajectory_a)):\n",
    "    plt.cla()\n",
    "\n",
    "    plt.plot([p_a[0], p_b[0]], [p_a[1], p_b[1]], '-.r', linewidth=1.0)\n",
    "    plt.plot([p_b[0], p_c[0]], [p_b[1], p_c[1]], '-.r', linewidth=1.0)\n",
    "    plt.plot([p_c[0], p_a[0]], [p_c[1], p_a[1]], '-.r', linewidth=1.0)\n",
    "    plt.scatter(p_center[0],p_center[1])\n",
    "    plt.plot(trajectory_a[0:i,0], trajectory_a[0:i,1], '-r',label=\"A\")\n",
    "    plt.plot(trajectory_b[0:i,0],trajectory_b[0:i,1],'-g',label=\"B\")\n",
    "    plt.plot(trajectory_c[0:i,0], trajectory_c[0:i,1], '-b',label=\"C\")\n",
    "    plt.legend()\n",
    "    plt.xlabel('x/m')\n",
    "    plt.ylabel('y/m')\n",
    "    plt.axis('square')\n",
    "    plt.grid(True)\n",
    "    plt.pause(0.001)\n",
    "#     camera.snap()\n",
    "\n",
    "\n",
    "# animation = camera.animate()\n",
    "# animation.save('trajectory3.gif')\n",
    "\n",
    "plt.show()\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.12 ('gobigger')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "0c7484b3574347463e16b31029466871583b0d4e5c4ad861e8848f2d3746b4de"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
